home *** CD-ROM | disk | FTP | other *** search
/ ASP Advantage 1994 2nd Q2 / The Association of Shareware Professionals - The Official ASP Advantage (2nd Quarter)(1994).bin / files / progming / bt / bt1.com (.txt) next >
Encoding:
Asc2Com (MorganSoft)  |  1993-02-14  |  60.0 KB  |  1,207 lines

  1.  
  2.                 B A S I C   T R A I N I N G        
  3.                         Part One                   
  4.                    by Steve Estvanik               
  5.  
  6. This is the first of a two part series that shows you the elements of the 
  7. Basic programming language. Basic Training covers the essentials to get you 
  8. started. Advanced Basic (available only to registered users), picks up from 
  9. that point and covers areas such as animation, error trapping and real time 
  10. event programming. (Run the REGISTER program for details on how to obtain 
  11. the second part.) 
  12.  
  13. The dialect of Basic that I use in this first part is based on the extended 
  14. Basic that comes with the IBM PC and most compatibles. The tutorial includes 
  15. many examples. The source code is also included with each tutorial, so you 
  16. can run it, modify it and experiment with it. I recommend that you make a 
  17. backup copy or rename the source files, though, before starting to 
  18. experiment. All the programs in this first part, and most of those in the 
  19. second can be run using just an interpreter, but if you're serious about 
  20. learning Basic, I strongly recommend that you purchase one of the compilers. 
  21.  
  22.  
  23. Part 1. Introduction
  24.  
  25. Basic History 
  26.  
  27. Basic was invented at Dartmouth in the 50's as a response to the problems of 
  28. instructing a computer. Previously, it was necessary for a programmer to 
  29. understand the computer at the machine level before you could get it to do 
  30. anything useful. This was much like requiring a course in auto mechanics 
  31. before you could hire a taxi. With Basic, you gain an assistant who 
  32. "interprets" their instructions and gets them where you want to go without 
  33. worrying about the "fiddly bits". Basic is only one of a series of 
  34. "languages" which have been developed for this purpose. In its original 
  35. form, it was limited compared to richer languages such as Fortran or Pascal. 
  36. In recent years, especially since the advent of microcomputers, Basic has 
  37. been enhanced and can now stand as tall as any of the other languages. Each 
  38. language has its advocates. In my daily consulting work and game design 
  39. programming, I use many languages routinely. Basic remains one of my choices 
  40. when I need to write a quick program of any sort, especially if it calls for 
  41. graphics. This easy-to-write quality combined with its simple structure 
  42. makes Basic a prime candidate for your first computer language. If you 
  43. already speak one computer language, learning Basic is an easy way to expand 
  44. your fluency. 
  45.  
  46.  
  47. Getting Started
  48.  
  49. Throughout this tutorial, I try to use commands that are common across all 
  50. Basics. When that's not possible (for example with graphics and sound), I 
  51. use Microsoft Basic for the IBM PC. Most other Basics used on IBM 
  52. compatibles are identical, but occasionally there are small differences. 
  53. Consult your user's manual to check on inconsistencies. When discussing 
  54. compilers, I use the TurboBasic/PowerBasic syntax.  
  55.  
  56. To get started, we'll create a simple, 2 line program. The program itself is 
  57. less important than the mechanics of how to create, save and run a Basic 
  58. program. Don't worry about what each line does right now, we'll cover that 
  59. soon. 
  60.  
  61. Start your version of Basic. If you're using an interpreter, just type:
  62.  
  63.     > basica     
  64. or
  65.     > gwbasic     
  66. or
  67.     > qbasic     
  68.  
  69. This loads interpreter Basic and you'll see the OK prompt.  Depending on the 
  70. version of DOS you have on your computer, there may be a different name for 
  71. the basic interpreter.  Check your DOS manual for the actual command name.  
  72.  
  73. If you're running a compiler such as PowerBasic or QuickBasic, start the 
  74. program, and run the examples in interactive mode ( alt-R).  (There's no OK 
  75. prompt when you use these products.)   If you're running Liberty Basic, 
  76. enter the command:  win LIBERTY or start the program from within Windows.
  77.  
  78.                                                                              
  79.  As an incentive, we'll send you a copy of the Liberty Basic compiler for    
  80.  Windows when you register.  This compiler lets you run Basic in the Windows 
  81.  environment without the need to learn all the complexities of Windows       
  82.  programming.  To print out the order form, enter the command:               
  83.       REGISTER   at the DOS prompt.                                          
  84.                                                                              
  85.  
  86. Now type the following 2 lines: 
  87.  
  88.     10 PRINT "hello there...."  
  89.     20    GOTO 10               
  90.  
  91. To test it out, type 
  92.  
  93.     RUN                         
  94.  
  95. or, if using a compiler, press alt-R (or otherwise invoke the Run command).
  96.  
  97. You should see your message repeated endlessly. Since your computer has more 
  98. patience than you for this sort of eternal game, press the <control><break> 
  99. keys to end the program. You've just written and run a complete Basic 
  100. program. This short program shows two quite useful statements. "Print" 
  101. causes anything coming after it to be echoed to the screen. "Goto" tells the 
  102. program to jump to the line indicated (in this case 10). Thus our program 
  103. will print the 2 words, then execute line 20. Since this line tells it to go 
  104. back to line 10, we get what's termed an "infinite loop". Usually this is 
  105. the result of a programming error or bug. 
  106.  
  107. This short program also introduces the concept of line numbers.  These 
  108. numbers let the interpreter know the order in which to try to execute the 
  109. commands.  It also gives you a reference for GOTO commands.  Interpreters 
  110. require line numbers.  Compilers can use them or not, as you like.  Modern 
  111. practise is to avoid them whenever possible, but I'll include them 
  112. occasionally for backwards compatibility.  
  113.                                            
  114. Our first program lacks elegance, and accomplishes nothing of much use, but 
  115. it gives us something to build on. More importantly, it gives us something 
  116. to save! You can save it now, by typing: 
  117.  
  118.     SAVE "Hello"                 
  119.  
  120. for the interpreter, or by using the File command, and the Save option if in 
  121. a compiler.
  122.  
  123. Then leave the Basic interpreter by typing 
  124.  
  125.      SYSTEM  
  126.  
  127. Leave the compiler by typing alt-X.
  128.  
  129. If you want to check that your program is really there, use the directory 
  130. command: 
  131.  
  132.     DIR H*.*                     
  133.  
  134. You should see "Hello.bas" (plus any other programs you have that start with 
  135. "h"). Note that Basic automatically assigns an extension of ".bas" to any 
  136. program you save. You can override this, but good programming practise 
  137. recommends against this. It will be easier to keep track of you rapidly 
  138. increasing selection of programs if you keep the extensions meaningful. To 
  139. run the program you have two choices. If you want to jump right into the 
  140. program, you just type: 
  141.  
  142.     BASICA Hello                 
  143.  
  144. This will load the Basic program and immediately begin to run your program. 
  145. Again, you'll need to break in order to stop this monster. Another approach 
  146. would be to load Basic first, then issue the command: 
  147.  
  148.     RUN "Hello"                  
  149.  
  150. Note that this second case requires the use of quotes, but the result is the 
  151. same, an endless stream of hello's. 
  152.  
  153. The next element we'll look at is the assignment statement.  This allows us 
  154. to set the value of variables.  Basic has three main categories of elements: 
  155.  
  156.     Reserved words -- special words like "print" and "goto"  
  157.         that have a special meaning to the interpreter        
  158.                                                                
  159.     Constants  -- numerical and string values like:          
  160.         2, 3.5 and "Hello there...".   (Note that string values
  161.         use quote marks to show their beginning and end.)      
  162.                                                                
  163.     Variables  -- anything else.                             
  164.  
  165. That's not quite fair, but it's close. Variables are what give life to an 
  166. otherwise rather boring collection of reserved words and constants (even 
  167. their names are boring!). A variable is what you create to represent some 
  168. other value. Think of them as containers that can hold many values. For 
  169. example, if I use the variable X, I can put many values into it. This 
  170. process is accomplished with the "LET" statement: 
  171.  
  172.     LET X = 10  
  173.  
  174. This says that X now has the value of 10. In fact very few programmers 
  175. bother with the LET statement (Many programmers have yet to discover that 
  176. you can use more than 2 fingers at a time on the keyboard, so they tend to 
  177. be brief.) A terser, and more common way is just to say: 
  178.  
  179.     X = 10      
  180.  
  181. This may look familiar to you if you've taken algebra or new-math type 
  182. courses. However, be careful!  The "=" sign should be read as "is assigned" 
  183. or "takes the value of".  Consider the following: 
  184.  
  185.     X = X + 1   
  186.  
  187. This says that X is now to be given the value of whatever X was before, plus 
  188. 1. In this case, 11. One of the advantages of an interpreter is that it can 
  189. give you an immediate response without running a program. You don't need 
  190. special commands to use this mode, just don't use line numbers. Thus if you 
  191. typed the initial line of our program, the interpreter would respond: 
  192.  
  193.     Hello there...  
  194.  
  195. Note that the quotes have disappeared. One use you can make of this feature 
  196. is as a calculator. If you type any mathmatical expression, the interpreter 
  197. will give you an answer. Eg, try the following to see how each is 
  198. interpreted: 
  199.  
  200.     2+1       
  201.     2*3       
  202.     4/2       
  203.     4-2       
  204.     2+4*5     
  205.     (2+4)*5   
  206.  
  207. Experiment until you feel comfortable with the way that arithmetic is 
  208. handled by the interpreter.  Notice, particularly, that the order of 
  209. interpretation depends on both the operator and any parentheses.  This is 
  210. called precedence. 
  211.  
  212. Basic also uses some defaults to describe whether a variable is a string, 
  213. integer or real number. Strings are indicated by a '$' as final digit, 
  214. integers as a '%', and real values as '!'. You tell Basic to set this 
  215. default with the command: 
  216.  
  217.     DEFINT A-Z   
  218.  
  219. This says any variable starting with the letters A to Z is an integer, 
  220. whether it has a '%' at the end or not. You could also define specific 
  221. variables to be strings or integers, but that starts to get confusing, so I 
  222. use the convention that all variables are integers unless otherwise 
  223. indicated.  
  224.  
  225. Now let's see how this works in a program.  We'll start with our hello 
  226. program, already in memory, and add to it: 
  227.  
  228.     10 PRINT "hello there....";X 
  229.     15 X = X + 1                 
  230.     20    GOTO 10                
  231.  
  232. Before trying this, make a prediction about what will happen.  You should 
  233. always try to predict what your program is going to do.  Remembering that 
  234. prediction will help when it does something you didn't anticipate. 
  235.  
  236.  
  237. Exercises
  238.  
  239. 1. Experiment with various combinations of arithmetic operations, until you 
  240. can predict what the results will be.  In particular, try examples which mix 
  241. multiplication and addition.  What is the effect of using parentheses? 
  242.  
  243. 2.  Use assignment statements to hold intermediate results. EG, 
  244.  
  245.      X = 2            
  246.      Y = 3            
  247.                       
  248.      X + Y            
  249.      X = X + Y        
  250.      PRINT X, Y       
  251.  
  252. (Note that when you assign a value, it isn't printed.) 
  253.  
  254.  
  255. Part 2. STRUCTURE AND STYLE
  256.  
  257. In the last chapter we looked at the most elementary statements in the Basic 
  258. language.  This time, we'll introduce the concept of branching and program 
  259. control.  In the next few installments we'll add loops, color, sound and 
  260. arrays.  At that point you'll be well equipped to start writing actual 
  261. programs. 
  262.  
  263.  
  264. MORE BASIC CONTROLS
  265.  
  266. A few more commands useful from within the interpreter:
  267.     LOAD "myprog"   --- gets your program from the disk
  268.     LIST            --- lists the entire program
  269.     LIST i - j      --- lists only lines i to j
  270.     LLIST           --- lists the program to your printer
  271.     RENUM           --- renumbers your program.  any relations within 
  272.                           your program are preserved. 
  273.  
  274. The compiler doesn't need line numbers, and you can skip them entirely, so 
  275. most of these commands aren't needed. Compilers have direct commands for 
  276. printing a file (usually under the FILE menu item.). I'll continue to use 
  277. line numbers in this tutorial, but my reason for doing so is that it's 
  278. easier to discuss a program when I can refer to particular line numbers. For 
  279. actual programs, I'll usually skip them. 
  280.  
  281. Structured programming is just a small part of the overall concept of 
  282. structured design. The root concept is to build a program from the top down. 
  283. It also discards the concept of flow charts. Here's the reason: Flow charts 
  284. are unnecessarily detailed. By the time you break a problem down to flow 
  285. chart level, you can usually write the code directly. They're so detailed, 
  286. that few programmers go back and change them when the program changes, so 
  287. flow charts are usually out of date as soon as they're written. Structured 
  288. programming does use diagramming techniques, but for our purposes we'll be 
  289. able to use pseudocode for all our designs. We approach the problem by 
  290. defining what we want to do at a very high level. For example, to create a 
  291. checkbook balancer, we might outline the following steps: 
  292.  
  293.       Enter initial balance     
  294.       Add deposits              
  295.       Subtract checks           
  296.       Show final balance        
  297.       Quit                      
  298.  
  299. Now we can elaborate this to describe each step in more detail: 
  300.  
  301.                                                        
  302.       Enter initial balance                            
  303.       Add deposits                                     
  304.           -- ask user if there are any more deposits   
  305.           -- if there are then                         
  306.                 get the next deposit                   
  307.                 add that amount to the balance         
  308.           .... repeat as necessary                     
  309.       Subtract checks                                  
  310.           -- ask user if there are any more checks     
  311.           -- if there are then                         
  312.                 get the next check                     
  313.                 subtract that amount from the balance  
  314.           .... repeat as necessary                     
  315.       Show final balance                               
  316.       Quit                                             
  317.                                                        
  318.  
  319. Note that some items require more elaboration than others. In some cases, we 
  320. could write the Basic code directly, so there's no need for further 
  321. refinement. Now, we're ready to write the actual code. Using this 
  322. structured, top down approach any problems become apparent from the start. 
  323. This text based way of describing a program is termed pseudocode, because 
  324. it's simpler than English, but not rigorous enough to feed to the computer. 
  325. It forms a useful link between human and computer. Well written pseudocode 
  326. is easily converted to any language, and forms an outline of the program. It 
  327. also suggests a preliminary set of comments. 
  328.  
  329.  
  330. IF THEN Statements
  331.  
  332. All programming statements that we'll look at are merely refinements or 
  333. alternate forms of 3 basic forms: assignments, loops and conditional 
  334. branching. Using only these 3 constructs, any possible program can be 
  335. written.  IF THEN, combined with the GOTO is an example of the third type of 
  336. statement, the branch.  In its simplest form, 
  337.  
  338.    IF { conditional statement } THEN 
  339.       { statement 1 }                
  340.    ELSE                              
  341.       { statement 2 }                
  342.  
  343. Last time we saw the simplest version of the loop: 
  344.  
  345.     10 X = X + 1    
  346.     20 PRINT X      
  347.     30    GOTO 10   
  348.  
  349. This is an infinite loop since it has no way to end.  One way to end 
  350. it would be by adding a conditional branch:
  351.  
  352.     10 X = X + 1             
  353.     20 PRINT X               
  354.     30 IF X < 10 GOTO 10     
  355.  
  356. Now, line 20 says that you should jump back up to line 10, ONLY if X is less 
  357. than 10.  (Basic uses the symbols <, >, <=, >= and <> to represent the ideas 
  358. "less than", "greater than", "less than or equal to", "greater than or equal 
  359. to" and "not equal to".  Try substituting these operations in the fragment 
  360. above to see their effects. 
  361.  
  362. The IF statement evaluates a conditional statement and then follows one of 
  363. several paths. You can have a simple IF statement without an ELSE. This says 
  364. that you want to do something only if the conditional is true, and you have 
  365. no other statements to process. Since the interpreted Basic IF statement 
  366. must all fit on one line, we can also use an expanded form when we have 
  367. several things that we want the statement to perform. We'll see examples of 
  368. this in the sample program, CHECKBK.BAS.  
  369.  
  370.     10 ' checkbk.bas                                                    
  371.     20 ' a simple check book balancing program                          
  372.     30 ' copyright 1987, 1992  s m estvanik                             
  373.     40 '                                                                
  374.     50 CLS                                                              
  375.     60 PRINT "Check Book Balancing Program"                             
  376.     70 PRINT                                                            
  377.     80 INPUT "What is your opening balance";BALANCE                     
  378.     90 PRINT                                                            
  379.     95 PRINT "Next transaction? (D/eposit, C/heck, Q/uit)"              
  380.     100 T$=INPUT$(1)                                                    
  381.     110 IF T$ <> "D" AND T$<> "d" GOTO 210    ' is this a deposit?      
  382.     120    INPUT "Amount of deposit";DEPOSIT                            
  383.     130    BALANCE = BALANCE + DEPOSIT        ' add to balance          
  384.     140    PRINT USING "New balance is $#####.##";BALANCE               
  385.     150       GOTO 90                                                   
  386.     210 IF T$ <> "C" AND T$<> "c" GOTO 300    ' is this a check?        
  387.     220    INPUT "Amount of check";CHECK                                
  388.     230    BALANCE = BALANCE - CHECK          ' subtract from balance   
  389.     240    PRINT USING "New balance is $#####.##";BALANCE               
  390.     250       GOTO 90                                                   
  391.     300 IF T$ <> "Q" AND T$<> "q" GOTO 90    ' do they want to quit?    
  392.     400 PRINT            ' we're done, so show the final balance        
  393.     410 PRINT USING "Final balance is $#####.##";BALANCE                
  394.     430 END                                                             
  395.  
  396. This version of the program uses only the simple statements that we've 
  397. discussed thus far. As we learn more about Basic, the exercises will suggest 
  398. ways you can return to this example to flesh it out. For now, try running 
  399. this program and follow its operation. (The example programs are included in 
  400. the tutorial package in a ready to run fashion. You can also clip out 
  401. segments of code from this tutorial and edit them.) 
  402.  
  403. Since interpreter statements must fit on one line, we're forced to use a 
  404. GOTO in order to create complex IF-THEN-ELSE statements. The compiler 
  405. doesn't limit us this way, so we can construct statements without ever using 
  406. GOTO's.  
  407.  
  408.     if X > 10 then             
  409.        PRINT X; " is > 10"     
  410.     else                      
  411.        PRINT X; " is <= 10"    
  412.  
  413.  
  414.  
  415. CHECK BOOK BALANCER
  416.  
  417. This is the first real program we've looked at, so let's examine it in more 
  418. detail. One of the goals of structured programming is to make programs that 
  419. are easy to modify and maintain in the future. To this end, you should 
  420. include a header at the top of each program that describes what it does, and 
  421. most important, when it was last modified and by whom. Then in writing the 
  422. program, use comments wherever they help to explain the flow of the program. 
  423. Comments are ignored by the Basic interpreter and the compiler. They're 
  424. indicated by either the word REM or more commonly, the apostrophe ('). 
  425. Comments starting with ' may be either the first or last elements on a line. 
  426. This allows short comments to be placed more precisely. Combined with a 
  427. standard indentation comments make the program structure more readable. For 
  428. example, I indent any statements after an IF statement. I also indent any 
  429. GOTO that starts a statement. In this way you can see that the statements 
  430. are dependent on the IF statement and that the control is passed by the 
  431. GOTO. You'll probably encounter any variants of indenting. The important 
  432. thing is to be consistent. Remember, though, that indenting is solely for 
  433. the human reader's benefit. The computer acts on what it reads, not how it's 
  434. formatted. Improper statements will not improve because of indenting. 
  435.  
  436. If you have multiple IF statements, then the indentations would add up: 
  437.  
  438.        IF { condition A} THEN          
  439.           IF { condition B } THEN      
  440.              { statement 1 }           
  441.           ELSE                         
  442.              { statement 2 }           
  443.        ELSE                            
  444.           { statement 3 }              
  445.  
  446. In this example, if condition A is true, a second check on condition B is 
  447. made, resulting in either statement 1 or 2 being executed.  If condition A 
  448. is false, then only statement 3 is executed and condition B isn't even 
  449. checked.  
  450.  
  451. The check book program first clears the screen (CLS), then announces itself 
  452. and uses a new command, INPUT, to ask for an opening balance. The INPUT 
  453. statement prints the string we give it (also called a 'prompt '). It adds a 
  454. question mark and then waits for the user to enter an answer and hit the 
  455. enter key. It stores that value in the variable BALANCE. INPUT is simple to 
  456. use, but does have some drawbacks. Try entering some non-numeric characters. 
  457. INPUT recognizes illegal characters, but its response is less than elegant. 
  458. Later we'll see some better ways for handling data input. After the balance 
  459. is entered, we enter the main loop of the program. The user indicates what 
  460. type of transaction comes next. (Note that we've changed the structure of 
  461. our program so that the user can enter deposits and checks in any order.) 
  462. The INPUT$(1) statement accepts precisely one character from the user and 
  463. doesn't need a carriage return. This is much friendlier since the user only 
  464. needs to press one key each time. 
  465.  
  466. Since we don't care whether the user enters an upper or lower case letter, 
  467. we shouldn't penalize them. Thus we'll allow either when we check. Lines 
  468. 110, 210 and 300 check to see if the value entered is not equal to one of 
  469. the valid codes. Thus in line 110, if T$ is not "T" or "t", we go to 210 to 
  470. check. At any stage, if we find a match, we do the appropriate processing, 
  471. then go back to get the next transaction. 
  472.  
  473. One last suggestion on GOTO's.  Do not jump up in the program, unless 
  474. absolutely necessary. That is, in reading a program, the normal flow should 
  475. be downwards. One exception would be a loop such as we have here. Line 90 
  476. starts the loop, and at the end of each transaction we return to it. 
  477.  
  478.  
  479. SUMMARY 
  480.  
  481. We've looked at some basic ideas of structured programming and created our 
  482. first useful program. We've also learned the IF-THEN construct. In addition, 
  483. we've already seen some of the elements of designing user friendly programs. 
  484.  
  485.  
  486. Exercises
  487.  
  488. 1.  Add a third option that allows the user to enter a monthly service fee.  
  489. Decide on a code, and add a new transaction that subtracts the fee.  Be sure 
  490. to change the prompt line to show this new code. 
  491.  
  492. 2.  The current program just ignores bad codes.  Add a message line that 
  493. tells the user that they've entered a bad code, then asks them to reenter 
  494. their choice. 
  495.  
  496. 3.  The PRINT USING statements are designed with home use in mind, so they 
  497. only have 5 figures in the display.  What happens if the user inputs a 
  498. number such as $100,100 ?  Assume that any number greater than 10000 is an 
  499. error.  Add an extra check to both the deposit and check section that 
  500. prevents these numbers from being included.  You should print an error 
  501. message and then go back to the transaction code input line without making 
  502. any changes to the balance. 
  503.  
  504. 4. Only positive numbers are valid for input.  Check that each number 
  505. entered is greater than 0 before allowing it. 
  506.  
  507.  
  508. Part 3. LOOPS, COLORS AND SOUND
  509.  
  510. In the last section, we learned a simple way to have our programs branch on 
  511. different choices.  This time, we'll add more structured loops, color and  
  512. sound.  In the following section, we'll look at arrays and data statements. 
  513.  
  514.  
  515. LOOPING 
  516.  
  517. In the previous program, we used GOTO's to move around.  This is discouraged 
  518. by purists and for good reason.  It's too easy to write spaghetti code with 
  519. meatball logic that jumps all over.  This makes it difficult for anyone else 
  520. to read or understand your code.  It's even hard to read your own code after 
  521. a week or two.  To review, if we wanted to add up a random series of 10 
  522. numbers given by the user, we could write: 
  523.  
  524.     10 x = 1                                          
  525.     20 sum = 0                                        
  526.     30 print x                                        
  527.     40 input "enter a number";n                       
  528.     50 sum = sum + n                                  
  529.     60 x = x + 1                                      
  530.     70 if x < 11 then goto 30                         
  531.     80 print "The sum of the numbers you gave is";sum 
  532.  
  533. Basic provides two other ways to accomplish this, both of which make the 
  534. program more flexible and easier to understand.  These are the FOR-NEXT and 
  535. the WHILE-WEND loops.  Using FOR-NEXT, we would write 
  536.  
  537.    10 sum = 0                                          
  538.    20 FOR x = 1 to 10                                  
  539.    30 print x                                          
  540.    40 input "enter a number";n                         
  541.    50 sum = sum + n                                    
  542.    60 NEXT x                                           
  543.    70 print "The sum of the numbers you gave is";sum   
  544.  
  545. Each FOR must have a corresponding NEXT.  The FOR-NEXT statements repeat 
  546. automatically.  The first number is the initial value, the second is the 
  547. final one.  You can also use the STEP command to move by more than one.  
  548. These loops can be nested as shown in the following example.  Note that the 
  549. last FOR started must be the first one finished. 
  550.  
  551.    10 input "Starting value (1-10)";x1 
  552.    20 input "Ending value (20-30)";x2  
  553.    30 print                            
  554.    40 for x = x1 to x2 step 2          
  555.    50    for y = 1 to 5                
  556.    60    print x*y;                    
  557.    70    next y                        
  558.    80 print                            
  559.    90 next x                           
  560.  
  561. Here we print a series of products, five to a line.  The semicolon ensures 
  562. that all 5 products are printed on a single line.  After Y's FOR-NEXT loop 
  563. is finished, we do a simple PRINT statement to move to the next line. 
  564.  
  565. Another form of looping is the WHILE-WEND pair.  Our initial example could 
  566. be reconstructed as: 
  567.  
  568.     10 sum = 0                                         
  569.     20 x = 1                                           
  570.     30 WHILE x < 11                                    
  571.     40    print x                                      
  572.     50    input "enter a number";n                     
  573.     60    sum = sum + n                                
  574.     70    x = x + 1                                    
  575.     80 WEND                                            
  576.     90 print "The sum of the numbers you gave is";sum  
  577.      
  578. The WHILE statement continues to loop until the condition is achieved.  
  579. Unlike the FOR-NEXT this might not happen.  Consider the following: 
  580.  
  581.     10 x = 1                           
  582.     20 WHILE x > 11                   
  583.     30    input "enter a number";n    
  584.     40    sum = sum + n               
  585.     50 WEND                           
  586.  
  587. This program contains a common mistake.  The value of X never changes, so 
  588. the loop repeats forever.   If you're testing and the program just wanders 
  589. off and never comes back, infinite loops are prime suspects.  Check for non-
  590. terminating WHILE loops by inserting a print statement. 
  591.  
  592. In the above examples, a FOR-NEXT loop is actually preferred, since we 
  593. really intend the loop to be executed a fixed number of times.  There are 
  594. many cases when only a WHILE will do.  WHILE's can handle loops when the 
  595. ending conditions are unclear.  For example: 
  596.  
  597.   10 pts = 0                                                          
  598.   20 die.roll = int(rnd*6) + 1 ' random number bet 1 and 6            
  599.   30 while die.roll <> 6 and pts < 20                                 
  600.   40    pts = pts + die.roll                                          
  601.   50    die.roll = int(rnd*6) + 1                                     
  602.   60 wend                                                             
  603.   70 if die.roll = 6 then pts = 0                                     
  604.   80 if pts>0 then print "You made";pts;"points" else print"You lost" 
  605.  
  606. This is a simple game in which you have a chance of winning up to 24 points 
  607. if the "die" manages to avoid coming up 6.  RND is a Basic function that 
  608. returns a random number between 0 and 1.  INT(RND*6) then converts this to a 
  609. random number between 0 and 5.  Since dice have no 0's we add one to it.  
  610. Here the while statement has 2 possible ways to end.  Either the die rolls a 
  611. 6, or the total points becomes 20 or greater.   If the loop ends with a die 
  612. roll of 6, then all points are lost.  
  613.  
  614. Exercise:  Make this game more interactive.  
  615.  
  616. After every die roll, show the current points and give the user a chance 
  617. to quit, keeping their current points.  Allow an unlimited number of 
  618. points to be accumulated.  Don't use any GOTO's in your solution. 
  619.  
  620.  
  621. COLORS
  622.  
  623. Assuming you have a CGA or EGA card, you can easily add colors and video 
  624. effects to your programs.  There are 8 colors, with 4 possibilities for each 
  625. color, defined as follows: 
  626.  
  627.                                                                     
  628.                  "dark"   "light"   dark, blinking  light,blinking  
  629.                 -------   ------    -------------       --------    
  630.     black           0         8           16                24      
  631.     blue            1         9           17                25      
  632.     green           2        10           18                26      
  633.     cyan            3        11           19                27      
  634.     red             4        12           20                28      
  635.     magenta         5        13           21                29      
  636.     brown           6        14           22                30      
  637.     white           7        15           23                31      
  638.                                                                     
  639.  
  640. On the CGA you can have any of the 32 colors as a foreground color.  This is 
  641. the color that letters and other characters will use.  You can also set any 
  642. of the 8 colors as a background color.  This allows reverse video effects.  
  643. Try the following: 
  644.  
  645.     10 color 7,0        
  646.     20 print "try me"   
  647.     30 color 0,7        
  648.     40 print "try me"   
  649.     50 color 15,1       
  650.     60 print "try me"   
  651.     70 color 31,1       
  652.     80 print "try me"   
  653.  
  654. The program included on the disk, COLORS.BAS gives a more extensive display 
  655. of the color range.  First it reproduces the table above, but using actual 
  656. colors for the numbers.  Then it shows all combinations of foreground and 
  657. background.  Note that if foreground and background are the same, the 
  658. letters can't be read. 
  659.  
  660. Color can be easily abused.  Clashing colors or too many colors distract 
  661. rather than attract.  Try to avoid using flashing messages for all but the 
  662. most important warnings.  In particular, don't use flashing colors for input 
  663. messages.  They are difficult to read.  Use colors which are easy to read, 
  664. with the more garish colors saved for special cases.  The most readable 
  665. color combinations on most displays are: 
  666.  
  667.        (bright) white  on blue    
  668.        (bright) yellow on blue    
  669.        (bright) white  on red          (useful for error messages)
  670.        (bright) yellow on red            "      "    "      "
  671.        (bright) white  on black   
  672.                 black  on white   
  673.        (bright) green  on black   
  674.        (bright) yellow on black   
  675.     
  676.        (bright) indicates either light or dark is ok.
  677.  
  678. We'll use colors more later when we look at more of the graphics commands.  
  679. For now, try the following problem: 
  680.  
  681.  
  682. Exercise:  Add color to the checkbook program given last time.  Use the 
  683. following scheme: 
  684.  
  685. First clear the screen to white on blue using the command:
  686.    COLOR 8,1 : CLS
  687.  
  688. For the first prompts, keep the color as white on blue.
  689. If a Debit is chosen, change color to bright yellow on blue.
  690. If a Credit is chosen, change color to bright white on blue.
  691. If the user makes a mistake, change to bright yellow on red.
  692.  
  693. Remember to change back to the original setting after each special color. 
  694.  
  695.  
  696. SOUNDS
  697.  
  698. Basic gives 2 methods for making sounds: SOUND and PLAY.  SOUND is easier 
  699. to learn, but harder to use effectively.  Its structure is
  700.  
  701.        SOUND frequency, duration    
  702.  
  703. Frequencies are in Hertz (cycles per seconds), durations in clock ticks 
  704. (about 18/second) 
  705.  
  706.       SOUND 220, 18       would thus give an A for one second.
  707.  
  708. In practise, you rarely try to duplicate music using SOUND.  Instead it's 
  709. useful for sirens and other sound effects.  For example, try 
  710.  
  711.     10 for i = 1 to 10   
  712.     20 sound i*100,5     
  713.     30 next              
  714.  
  715. Or, consider the following:
  716.  
  717.     10 FOR I=1 TO 9 'phaser sounds                          
  718.     20 RII!=I/( 90)                                         
  719.     30    FOR J= 1000 TO 2700 STEP 200:SOUND J,RII!:NEXT J  
  720.     40 NEXT I                                               
  721.  
  722. Play with the various loop commands to achieve different effects.  Different 
  723. CPU speed may affect these sounds, so they are not generally recommended.  
  724. Most compilers have a timer function that allows you to delay a set amount 
  725. of time.  
  726.  
  727. PLAY has a more complex syntax.  I'll briefly introduce it here.  The best 
  728. way to learn this command is to practise using it in various ways.
  729.  
  730. PLAY requires a string that uses Microsoft's music command language.  Some 
  731. of the commands are:
  732.  
  733.     A-G  with optional # or -, play the notes A-G with sharps or flats.
  734.  
  735.     O n  sets the octave.  An octave goes from C to B.  
  736.            n can range from 0 to 6.
  737.  
  738.     N x  plays note x, from 0 to 84.  This is an alternative to using 
  739.         the notes and octaves, but is less useful if you're 
  740.         transcribing from musical notation.
  741.  
  742.     L n  sets the length of the note. Can range from 1 to 64.
  743.         Any value, can be played, even 23rd notes!
  744.  
  745.     P n  pauses for length n.
  746.  
  747.     T n  sets the tempo in quarter notes /minute.  For example
  748.          Largo is 40-60, Adagio is 66-76, Allegro is 120-168.
  749.  
  750. To play a sequence, you just construct a string and give it to PLAY.
  751.  
  752.        x$ = "efg-fed#"                             
  753.        PLAY "T120 L8 o2" + x$ + "p4 o3 l16 " + x$   
  754.  
  755. We first assign a sequence of notes to x$.  Here we're playing E, F, G flat, 
  756. F, E and D sharp.  Then we play this sequence of notes at tempo 120, using 
  757. eighth notes in octave 2.  We pause for a quarter note's time, then move up 
  758. an octave, change to sixteenth notes and repeat the phrase. 
  759.  
  760. Here's some more interesting music to practise with:
  761.  
  762.     10 '================== little mathy groves       
  763.     20 PLAY "t160 o3"                                
  764.     30 PLAY "l8 g4eee4ddg4efe4.d"                    
  765.     40 PLAY "gag4a4gab2 p4ga b4b4b4.b g4b4d4.g "     
  766.     50 PLAY "o2b4 o3 d4 e4f4g4.ge4d4 o2b4o3d4e2."    
  767.     60 X$=INPUT$(1)                                  
  768.     70 '===================== rising sun blues       
  769.     80 T1$="t200 o2 l4 ge2gb2 o3c+ o3d2 e8d8 o2b2."  
  770.     90 T2$="p2 b o3 e2ef8e.d o2b8o3c."               
  771.     100 PLAY T1$+T2$                                 
  772.  
  773. These are some phrases from folk songs.  Note that I've used an alternate 
  774. way of designating the length in line 30. The G4 says to override the 
  775. default length of 8 for that one note.  You can practise by transcribing 
  776. your favorite music, then changing tempo, or playing style. 
  777.  
  778. In the second example, note that several phrases can be described 
  779. independently then built up as needed. 
  780.  
  781.  
  782.  4. ARRAYS and DATA STATEMENTS
  783.  
  784. Last chapter, we added color and sound to our programming kit.  We also saw 
  785. several ways to repeat instructions.  In the next chapters we'll finish our 
  786. introduction by looking at more efficient ways to store data, better methods 
  787. for performing repetitive sections of a program, and methods for storing 
  788. data in files.  
  789.  
  790. ARRAYS
  791. Arrays are a convenient way of representing groups of data.  Consider the 
  792. months of the year.  We could store them in a program as follows: 
  793.  
  794.       MONTH1$ = "JAN"   
  795.       MONTH2$ = "FEB"   
  796.       MONTH3$ = "MAR"   
  797.       MONTH4$ = "APR"   
  798.       ...               
  799.  
  800. Then when we want to print month X we could code:
  801.  
  802.        IF X = 1 THEN PRINT MONTH1$  
  803.        IF X = 2 THEN PRINT MONTH2$  
  804.        IF X = 3 THEN PRINT MONTH3$  
  805.        IF X = 4 THEN PRINT MONTH4$  
  806.        ...                          
  807.  
  808. This isn't terribly efficient.  And what if, instead of 12 items, we had 
  809. hundreds or THOUSANDS?  We might want to get a total of all incomes in a 
  810. particular group.  If there were just a few people to total we could code 
  811.  
  812.      TOTAL.INCOME = INCOME1 + INCOME2 + INCOME3...    
  813.  
  814. But do you really want to write the equation for 10,000 people?  Luckily we 
  815. have arrays.  An array is a grouping of data that still lets us access 
  816. individual elements.  An array is defined by a dimension statement: 
  817.  
  818.      DIM MONTH$(12)  
  819.  
  820. This defines a group of 13 strings starting with MONTH$(0) and ending with 
  821. MONTH$(12).  What's in each one is still up to the programmer and the 
  822. program, but now we can access a particular item much easier.  Using the 
  823. months example from above, we still need to define each item or element of 
  824. the array : 
  825.  
  826.        MONTH$(1) = "JAN"  
  827.        MONTH$(2) = "FEB"  
  828.        MONTH$(3) = "MAR"  
  829.        MONTH$(4) = "APR"  
  830.        ....               
  831.  
  832. So far no big change, but look at how easy it is to find a particular 
  833. value.  Now we can get month X directly:
  834.  
  835.        PRINT month$(X)    
  836.  
  837. X is called an index.  If we wanted to print all twelve months, we could 
  838. use a loop:
  839.  
  840.        FOR X = 1 to 12    
  841.        PRINT MONTH$(X)    
  842.        NEXT               
  843.  
  844. Compare this to the hassle of trying to print all months the first way.  
  845. When you have larger arrays, the savings become spectacular.  These arrays 
  846. are called singly dimensioned arrays since there is only one index.  But we 
  847. can also think of times we'd like to use several dimensions.  Maybe we want 
  848. to track the production of several product lines over several months.  We 
  849. could set 
  850.  
  851.        DIM PRODUCT(10, 12) 
  852.  
  853. This defines an array that will hold sales information on 10 products for 
  854. each of 12 months.  Thus PRODUCT(5, 11) would hold the sales for the 5th 
  855. product for the 11th month.  Note, we could just as easily defined this as 
  856.  
  857.        DIM PRODUCT(12, 10)  
  858.  
  859. where we have data for each month for each product.  Now the data for the 
  860. 5th product for the 11th month would be PRODUCT(11, 5).  The first method is 
  861. the one usually preferred.  Think of the array as starting with the larger 
  862. category (here, product type) on the left, moving to subcategories on the 
  863. right (months).  
  864.  
  865. We can extend the number of dimensions to 3 if we want to show the sales 
  866. for each day of the month:
  867.  
  868.        DIM PRODUCT(10, 12, 31)  
  869.  
  870. In theory you can have 255 dimensions.  In reality you'd run out of memory 
  871. well before using all 255.  Each added dimension will raise the required 
  872. storage by at least a factor of 2.  The total memory space that is available 
  873. to Basic is only 64k.  Thus even in our products example, we move from the 
  874. 11 elements of PRODUCT(10) to the 143 of PRODUCT(10,12) to 4576 for 
  875. PRODUCT(10,12,31)  ( 11*13*32 ).  Another problem is the fact that most 
  876. people have trouble conceptualizing more than 3 or 4 dimensions.  Usually 
  877. it's easier to restate the problem.  In years of programming I can recall 
  878. only a few instances where more than 3 dimensions made any practical sense. 
  879.  
  880. Arrays form the basis of most data processing applications, especially in 
  881. areas like spreadsheets and statistics. In Basic, an array is considered to 
  882. start from item 0. Many programmers forget about this element and though it 
  883. will take up a little more space, you often can ignore it too. But there are 
  884. some cases where it comes in handy. Suppose we have a 5 by 5 array and want 
  885. to get totals in each direction. Using our product by month example, we'd 
  886. want to get totals for each product for all months and totals for each month 
  887. for all products. Without arrays we'd have to construct separate assignment 
  888. statements for each total. (No, this won't be assigned as an exercise. But 
  889. just think how long it would take to do this, and how many places you could 
  890. mistype and cause an error!) The short program total.bas shows this: 
  891.  
  892.     10  ' totals.bas                                   
  893.     20  ' do cross totals on an array                  
  894.     30  DIM X(5,5)                                     
  895.     40  X(0,0) = 0                   ' grand totals    
  896.     50  FOR I = 1 TO 5                                 
  897.     60  X(I,0) = 0                                     
  898.     70     FOR J = 1 TO 5                              
  899.     80     X(I,J) = RND(1)*10                          
  900.     90     X(I,0) = X(I,0) + X(I,J)  ' line totals     
  901.     100    X(0,J) = X(0,J) + X(I,J)  ' column totals   
  902.     110    X(0,0) = X(0,0) + X(I,J)  ' grand total     
  903.     120    NEXT                                        
  904.     130 NEXT                                           
  905.     140 FOR I = 5 TO 0 STEP -1                         
  906.     150    IF I = 0 THEN PRINT "  "   ' extra space    
  907.     160    FOR J = 5 TO 0 STEP - 1                     
  908.     170    IF J = 0 THEN PRINT "  ";  ' extra row      
  909.     180    PRINT USING " ###.## ";X(I,J);              
  910.     190    NEXT                                        
  911.     200    PRINT                                       
  912.     210 NEXT                                           
  913.  
  914. First we define an array X to be 5 by 5.  (Later you can expand this to more 
  915. rows and columns, but you may run out of space to display it on the screen.)  
  916. Since we're only going to use the elements that have indices greater than 1, 
  917. we have 3 classes of elements that would otherwise be wasted.  These are all 
  918. X(i, 0), X(0, j) and the single element X(0,0).  We'll use these as follows: 
  919.  
  920.        X(i, 0) will store the total for row i                      
  921.        X(0, j) will store the total for column j                   
  922.        X(0, 0) will store the grand total of all rows and columns  
  923.  
  924. Line 40 sets the grand total to 0.  Now we have a double-do loop (not to be 
  925. confused with the DOO-WAH loop that's often used for timing.)  Since this is 
  926. just a test, we don't want to burden the user by having them enter all the 
  927. data, so in line 80 we just fill in a random number from 0 to 9.  Then we 
  928. accumulate the line and column totals in lines 90-110.  That's all there is 
  929. to it.  To display the results we'll use a pair of reversed loops.  This 
  930. will present the 0 indices in the last rows and columns, so the table will 
  931. look more like the spreadsheet format you may be used to.  In the lower 
  932. right corner is X(0,0) the grand total. 
  933.  
  934. The PRINT USING statement " ###.##" says to print the value of X using 8 
  935. spaces.  The value will be shown as up to 3 digits with 2 additional 
  936. places shown after the decimal place.
  937.  
  938. ------------------------------------------------
  939.  
  940. Exercises:
  941.  
  942. 1. Change the PRINT USING statement to show only 2 digits with one decimal 
  943. place.  Reduce the total number of spaces used to 6.
  944.  
  945. 2. Why do we need the PRINT USING statement in the first place?  Hint: take 
  946. it out, replacing it with a simple PRINT X(I,J).
  947.  
  948. 3.Change this program to allow creation of a spreadsheet that will produce a 
  949. table showing 6 different products in columns, with 12 months as the rows. 
  950. Include labels for each row and col.  You can use something simple like 
  951. "Month 9" and "Prod 2", but should use a loop rather explicit numbered 
  952. labels. 
  953. ------------------------------------------------
  954.  
  955. As you program you'll find countless ways to use arrays.  Few programs of 
  956. any size can get along without them.  Even small programs benefit.  Let's 
  957. look at another use.  Program PLAYARRY.BAS shown below defines a series of 
  958. strings. 
  959.  
  960.     1 ' playarry.bas                                          
  961.     10 PLAY "t220"                                            
  962.     20 L$(1) = "l8o1 e "                                      
  963.     30 L$(2) = "l8o1 g "                                      
  964.     40 L$(3) = "l8o1 f "                                      
  965.     50 H$(1) ="l32o3 defgab o4 cd"                            
  966.     60 H$(2) ="l32o4 edc o3 bagfe"                            
  967.     70 H$(3) = "l32 o3 dc o2bagfed"                           
  968.     80 H$(4)= "l32 o2 cdefgab o3c"                            
  969.     90 FOR K = 1 TO 3                                         
  970.     100 IF K = 3 THEN PLAY "t220" ELSE PLAY "t180"            
  971.     110 FOR I = 1 TO 12                                       
  972.     120 IF K = 1 OR K = 3 THEN PLAY L$((I MOD 3)+1)           
  973.     130 IF K = 2 OR K = 3 THEN PLAY H$((I MOD 4)+1)           
  974.     135 ' quit as soon as any key is pressed                  
  975.     140 IF INKEY$ > "" THEN 180                               
  976.     150 NEXT                                                  
  977.     160 NEXT                                                  
  978.     170 GOTO 90                                               
  979.     180 END                                                   
  980.  
  981. DATA Statements 
  982.  
  983. So far, whenever we've wanted to define initial values, we've just used 
  984. assignment statements.  An alternative is the DATA statement.  In its 
  985. simplest form, it consists of a READ statement and a DATA statement 
  986.  
  987.        READ I  
  988.        DATA 5  
  989.  
  990. When these two statements are executed, I is assigned the value 5.  In this 
  991. case there isn't much savings over the more straightforward 
  992.  
  993.        I = 5   
  994.  
  995. But the DATA statement is more flexible.  You can define a whole array 
  996. with one concise statement:
  997.  
  998.        FOR I = 1 to 10 : READ X(I) : NEXT  
  999.        DATA 1,3,4,5,6, 6,5,6,5,6           
  1000.  
  1001. Otherwise this would take 10 separate statements.  You can also make DATA 
  1002. statements conditional.  RESTORE declares where the initial data statement 
  1003. begins. 
  1004.  
  1005.     10 IF X = 1 THEN RESTORE 20 ELSE RESTORE 30 
  1006.     20 DATA 1,2,3                               
  1007.     30 DATA 4,5,6                               
  1008.     40 READ I,J,K                               
  1009.  
  1010. Here, when X is 1, I,J,K will be read as 1,2,3 otherwise they will be set to 
  1011. 4,5,6.  RESTOREs are useful when you have many DATA statements in a program.  
  1012. Normal usage places DATA statements near the corresponding READ statements, 
  1013. but Basic doesn't care.  The program uses the next sequential DATA element.  
  1014.  
  1015.        DATA 1,2,3                     
  1016.        READ X, Y                      
  1017.        ...... [ much more code ]      
  1018.        DATA 4,5,6                     
  1019.        READ Z                         
  1020.  
  1021. In this fragment, Z is set to 3, since only 2 READ's were done before it.  
  1022. Be careful when coding DATA and READ statements. Having too few data 
  1023. elements will cause a syntax error.  Having more data elements than 
  1024. corresponding READ's is allowed, but could cause hard to find errors. A 
  1025. safety measure would be to print out the last of a series of read when 
  1026. testing so that you can ensure that values are being set the way you 
  1027. intended. 
  1028.  
  1029. Strings in DATA statements cause several additional concerns.  When all the 
  1030. strings are single words, they could be read in separated by commas, but if 
  1031. some of them have commas as part of the item, then you'll need to delimit 
  1032. each string by quotes.  Thus if we used the statements 
  1033.  
  1034.        DATA Seattle, WA, Bar Harbor, ME 
  1035.        READ FROM$, TO$                  
  1036.        PRINT FROM$, TO$                 
  1037.  
  1038. we'd see
  1039.  
  1040.        Seattle     WA                   
  1041.  
  1042. In fact we want the city and state to be paired, so we'd need to write
  1043.  
  1044.        DATA "Seattle, WA", "Bar Harbor, ME"  
  1045.  
  1046.  
  1047. Let's look at another way to use arrays and data statements.  DRAWBOX1.BAS 
  1048. prints boxes on the screen.  
  1049.  
  1050. First, a slight digression. CHR$() is a special feature of Basic that 
  1051. returns the ASCII equivalent of a number. ASCII is a set of symbols used in 
  1052. programming. The first 128 characters (0-127) are rigidly defined. Some 
  1053. computers such as the IBM PC define an additional set for the numbers 128-
  1054. 255 but these are not standardized. In the IBM system these include the 
  1055. symbols for creating boxes and forms. It's easy to confuse ASCII characters 
  1056. and their corresponding numbers. All characters and numerals are ASCII 
  1057. characters. Thus the upper case 'A' is 65. Adding 1 to it gives ASCII 66 or 
  1058. 'B'. Most confusion comes with numbers. ASCII 49 is the character '1'. Later 
  1059. we'll see ways of using this numeric feature in sorting and alphabetizing. 
  1060. For now all you need to know is that PRINT CHR$(X) will display the X'th 
  1061. ASCII character. Most Basic manuals have an ASCII chart as an Appendix. 
  1062. Another option would be to write a short Basic program that prints all 
  1063. values. The converse of the CHR$() function is ASC(). This returns the ASCII 
  1064. value of a given character. Thus 
  1065.  
  1066.        PRINT ASC("1")     
  1067.  
  1068. would print 49.
  1069.  
  1070.        FOR I = 0 to 255   
  1071.        LPRINT I;CHR$(I)        ' print item and ASCII equiv to printer
  1072.        NEXT               
  1073.  
  1074. This will end up 5 pages long.  Try writing a program that will format this 
  1075. into 8 columns.  Thus the first line would have the 0, 32, 64, 96,... 
  1076. elements, the second line would have 1, 33, 65, 97,...  You can do this with 
  1077. either one loop and a long print statement or nested loops and a single 
  1078. print statement.  Remember that a semicolon (;) after a print line will 
  1079. prevent a skip to the next line.  If you use this method, you'll need to 
  1080. have a separate print statement to shift to the next line. 
  1081.  
  1082. Now we're ready to draw a box:
  1083.  
  1084.     1  ' drawbox1.bas                                    
  1085.     10  DIM CORNER(4)                                    
  1086.     20  KEY OFF                                          
  1087.     30  W = 15 ' width of box                            
  1088.     40  H = 6 ' height of box                            
  1089.     50  DATA 205, 186, 201, 187, 188, 200                       
  1090.     60  READ HORIZ, VERTICAL                             
  1091.     70  FOR I = 1 TO 4                                   
  1092.     80  READ CORNER(I)                                   
  1093.     90  NEXT                                             
  1094.     100 X = 0                                                   
  1095.     110 WHILE X < 1 OR X > 25 - H                        
  1096.     120    INPUT "Upper left row";X                      
  1097.     130 WEND                                             
  1098.     140 Y = 0                                                   
  1099.     150 WHILE Y < 1 OR Y > 80 - W                        
  1100.     160    INPUT "Upper left column";Y                   
  1101.     170 WEND                                             
  1102.     180 COLOR 15,1                                       
  1103.     190 CLS                                              
  1104.     200 LOCATE X,Y                                       
  1105.     210 PRINT CHR$(CORNER(1));      ' top line           
  1106.     220 FOR I = 1 TO W-2 : PRINT CHR$(HORIZ); : NEXT     
  1107.     230 PRINT CHR$(CORNER(2));                           
  1108.     240 FOR J = 1 TO H - 2    ' create middle section    
  1109.     250 LOCATE X+J,Y                                     
  1110.     260 PRINT CHR$(VERTICAL);                            
  1111.     270 FOR I = 1 TO W-2 : PRINT CHR$(32); : NEXT        
  1112.     280 PRINT CHR$(VERTICAL);                            
  1113.     290 NEXT                                             
  1114.     300 LOCATE X+H-1, Y                                  
  1115.     310 PRINT CHR$(CORNER(4));      ' bottom line        
  1116.     320 FOR I = 1 TO W-2 : PRINT CHR$(HORIZ); : NEXT     
  1117.     330 PRINT CHR$(CORNER(3));                           
  1118.     340 END                                              
  1119.  
  1120. First we set the width and height of the box we want to draw.  Then we 
  1121. read in values for the horizontal and vertical linedrawing characters ═ 
  1122. and ║.  These are ascii values 205 and 186.  Line 60 reads their values and 
  1123. stores them as variables HORIZ and VERTICAL.  Next, we need the the four 
  1124. corners: 
  1125.  
  1126.        ╔ ╗     
  1127.                
  1128.        ╚ ╝     
  1129.  
  1130. The ascii values for the corners (201, 187, 188 and 200) are stroed in an 
  1131. array (lines 70-90). We next ask for row and column coordinates.  The 
  1132. program draws the upper left corner, a row of horizontal characters and the 
  1133. upper right corner.  For each intermediate line, we draw a vertical section, 
  1134. spaces and another vertical.  We finish with the 2 lower corners connected 
  1135. by another horizontal line. 
  1136.  
  1137.  
  1138. Exercises
  1139.  
  1140. 1. Allow user to draw several boxes without erasing them You'll need to 
  1141. keep the input on several lines, eg, lines 21 and 22.  Clear each line 
  1142. before prompting for new data. 
  1143.  
  1144. 2. Check the ASCII table in the back of your Basic manual.  Find the 
  1145. characters that can be used to make a single lined box and add them to the 
  1146. program.  Use a 2 dimensional array.  That is redefine the arrays to be 
  1147. CORNER(4,2), HORIZ(2), VERTICAL(2) and then ask the user whether they want 
  1148. a single or double lined box. 
  1149.  
  1150. 3. More involved: This box is drawn from the top down.  An alternative 
  1151. would be to draw it as if a pen were sketching it.  Rewrite the program to 
  1152. draw the first line, then drop down the right hand side, come back along 
  1153. the bottom right to left, then draw up to the original corner.  For the 
  1154. sides you'll need to recalculate the x,y position each time.  A FOR-NEXT 
  1155. loop works fine. 
  1156.  
  1157. ---------------------------------------------------------
  1158.  
  1159. We've looked at several different applications of arrays.  We've also 
  1160. managed to review many of the constructs that we covered in previous 
  1161. sessions.  In the next installments we'll refine these ideas as we start 
  1162. considering how to build larger programs in a structured manner. 
  1163.  
  1164. Exercise
  1165. In preparation for next time, try this as a final exercise:
  1166.  
  1167.        DIM DAYS(12)                                
  1168.        DATA 31,28,31, 30,31,30, 31,31,30, 31,30,31 
  1169.        FOR I = 1 TO 12 : READ DAYS(I) : NEXT       
  1170.  
  1171. Write a short program that takes as input a pair of numbers -- month and 
  1172. day.  Calculate the number of days elapsed since the start of the year and 
  1173. the number of days till the end of the year. 
  1174.  
  1175.  
  1176. End of Part One
  1177. This completes the first part of BASIC TRAINING TUTORIAL.  The next section 
  1178. covers Files, graphics and other topics.  It's still part of the BASIC 
  1179. TRAINING shareware package.  
  1180.  
  1181. If you're interested in studying more of what Basic can do, and what a 
  1182. compiler can add, the next Tutorial in this series will help.  When you 
  1183. register, you get it for free.  
  1184.  
  1185. ADVANCED BASIC.  Topics include: Animation techniques, Shape Shifting 
  1186. techniques, Error Handling, Chaining, Windows, Peek / poke, Bload / bsave, 
  1187. Plus, details on differences between interpreters and compilers. And 
  1188. complete source for all examples.  Advanced Basic is ONLY available to 
  1189. registered users.  
  1190.  
  1191. Registration costs only $20, and you will receive The Advanced Basic 
  1192. Tutorial as a bonus, along with more source code for all the examples in 
  1193. that tutorial.  
  1194.  
  1195. In addition, when you register you also get an evaluation copy of the 
  1196. LIBERTY Basic compiler for Windows.  This program lets you develop Basic 
  1197. programs in the Windows environment, without the need for the Windows 
  1198. Software Development Kit.
  1199.  
  1200. To Register, return to DOS, and enter the command:
  1201.        REGISTER  
  1202. An order form will be printed for you.  Or send $20 + $4 shipping to:
  1203.         Cascoly Software    
  1204.         4528 36th Ave NE    
  1205.         Seattle WA 98105    
  1206.  
  1207.